package com.example.schooljava.exception;

import com.example.schooljava.util.HttpStatus;
import com.example.schooljava.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 功能描述
 *
 * @author: LDH
 * @date: 2022年05月16日 19:23
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 用户 token 过期
     * @return
     */
    @ExceptionHandler(value = TokenAuthExpiredException.class)
    @ResponseBody
    public Result tokenExpiredExceptionHandler(){
        log.warn("用户 token 过期");
        return new Result<>().error("","token 过期",400);
    }

    /**
     * 功能描述: 参数异常捕获
     * @Param: [e]
     * @Return: com.library.common.Result
     * @Author: LDH
     * @Date: 2022/6/20 15:51
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Result handleValidation(MethodArgumentNotValidException e) {
        BindingResult exceptions = e.getBindingResult();
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                FieldError fieldError = (FieldError) errors.get(0);
                return new Result<>().error(e.getClass().getName(), fieldError.getDefaultMessage(),HttpStatus.BAD_REQUEST);
            }
        }
        return new Result<>().error("","参数校验异常", HttpStatus.BAD_REQUEST);
    }


    /**
     * 处理自定义的业务异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public Result bizExceptionHandler(HttpServletRequest req, BizException e){
        log.error("发生业务异常！原因是: {}",e.getMessage());
        return new Result<>().error(null,e.getErrorMsg(),e.getErrorCode());
    }

    /**
     * 处理空指针的异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    public Result exceptionHandler(HttpServletRequest req, NullPointerException e){
        log.error("发生空指针异常: {}",e.getMessage());
        return new Result<>().error(null,"空指针异常",HttpStatus.ERROR);
    }


    /**
     * 处理其他异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    public Result exceptionHandler(HttpServletRequest req, Exception e){
        log.error("未知异常: {}",e.getMessage());

        return new Result<>().error(null,"服务器处理异常",HttpStatus.ERROR);
    }
}